import {
	INavigateParam,
	IParam,
	ITreeAbility,
	ITreeExpBarAbility,
	ITreeExpBarController,
	ITreeExpBarControllerParams,
	ITreeExpBarModel,
	ITreeExpBarStore,
	ITreeModel,
	ITreeNodeModel,
	TreeExpBarActionType,
} from '@/core/interface';
import { computedNavData, deepCopy } from '@/core/utils';
import { ExpCtrlController } from './exp-ctrl-controller';

/**
 * 树导航栏控制器
 *
 * @export
 * @class TreeExpBarController
 * @extends {ExpCtrlController<TreeExpBarActionType, ITreeExpBarStore, ITreeExpBarAbility>}
 * @implements {ITreeExpBarController<ITreeExpBarStore, ITreeExpBarAbility>}
 */
export class TreeExpBarController
	extends ExpCtrlController<
		TreeExpBarActionType,
		ITreeExpBarStore,
		ITreeExpBarAbility
	>
	implements ITreeExpBarController<ITreeExpBarStore, ITreeExpBarAbility>
{
	/**
	 * 树导航栏模型
	 *
	 * @protected
	 * @type {ITreeExpBarModel}
	 * @memberof TreeExpBarController
	 */
	protected declare readonly model: ITreeExpBarModel;

	/**
	 * Creates an instance of TreeExpBarController.
	 * @param {ITreeExpBarControllerParams<TreeExpBarActionType, ITreeExpBarAbility>} params
	 * @memberof TreeExpBarController
	 */
	public constructor(
		params: ITreeExpBarControllerParams<
			TreeExpBarActionType,
			ITreeExpBarAbility
		>
	) {
		super(params);
		this.ctrlInit(params);
	}

	/**
	 * 处理部件初始化
	 *
	 * @protected
	 * @param {ITreeExpBarControllerParams<TreeExpBarActionType, ITreeExpBarAbility>} params
	 * @memberof ListExpBarController
	 */
	protected processCtrlInit(
		params: ITreeExpBarControllerParams<
			TreeExpBarActionType,
			ITreeExpBarAbility
		>
	) {
		super.processCtrlInit(params);
		Object.assign(this.store, { selection: {} });
	}

	/**
	 * 处理选中数据变化
	 *
	 * @param {IParam[]} selections
	 * @memberof TreeExpBarController
	 */
	public handleSelectionChange(selections: IParam[]) {
		if (!selections || selections.length === 0) {
			this.calcNavigateToolbarState(true);
			return;
		}
		const mdCtrl = this.getMDCtrlAbility();
		if (mdCtrl) {
			const select = selections[0];
			const nodeType = select.id.split(';')[0];
			const treeModel: ITreeModel = mdCtrl.getModel() as ITreeModel;
			const { treeNodes } = treeModel;
			const treeNodeModel = treeNodes.find(
				(node: ITreeNodeModel) => nodeType == node.nodeType
			);
			if (treeNodeModel) {
				const { tempContext, tempViewParams } = this.computeNavParams(
					select,
					treeNodeModel
				);
				const param: INavigateParam = {
					data: select,
					navViewName: treeNodeModel.navViewName,
					navData: {
						context: tempContext,
						viewParams: tempViewParams,
					},
				};
				this.calcNavigateToolbarState(
					select.curData ? false : true,
					select.curData
				);
				this.emit('selectionChange', [param]);
			}
		}
	}

	/**
	 * 搜索
	 *
	 * @param {string} searchValue
	 * @memberof TreeExpBarController
	 */
	public search(searchValue: string) {
		this.searchValue = searchValue;
		const mdCtrl = this.getMDCtrlAbility() as ITreeAbility;
		if (mdCtrl) {
			mdCtrl.refreshAllNode({ query: searchValue });
		}
	}

	/**
	 * 计算导航参数
	 *
	 * @private
	 * @param {IParam} data
	 * @param {ITreeNodeModel} treeNodeModel
	 * @return {*}  {{ tempContext: any, tempViewParams: any }}
	 * @memberof TreeExpBarController
	 */
	private computeNavParams(
		data: IParam,
		treeNodeModel: ITreeNodeModel
	): { tempContext: any; tempViewParams: any } {
		const tempContext: any = {};
		const tempViewParams: any = {};
		const { context } = this.store;
		if (data.navFilter) {
			Object.defineProperty(tempViewParams, data.navFilter, {
				value: data.srfkey,
				writable: true,
				enumerable: true,
				configurable: true,
			});
		}
		Object.assign(tempContext, deepCopy(context));
		if (data.srfappctx) {
			Object.assign(tempContext, deepCopy(data.srfappctx));
		}
		if (data.srfparentdename) {
			Object.assign(tempContext, { srfparentdename: data.srfparentdename });
		}
		if (data.srfparentdemapname) {
			Object.assign(tempContext, {
				srfparentdemapname: data.srfparentdemapname,
			});
		}
		if (data.srfparentkey) {
			Object.assign(tempContext, { srfparentkey: data.srfparentkey });
		}
		if (
			treeNodeModel.navigateContext &&
			Object.keys(treeNodeModel.navigateContext).length > 0
		) {
			const tempData: any = data.curData ? data.curData : {};
			const _context = computedNavData(
				tempData,
				tempContext,
				tempViewParams,
				treeNodeModel.navigateContext
			);
			Object.assign(tempContext, _context);
		}
		if (
			treeNodeModel.navigateParams &&
			Object.keys(treeNodeModel.navigateParams).length > 0
		) {
			const tempData: any = data.curData ? data.curData : {};
			const _params = computedNavData(
				tempData,
				tempContext,
				tempViewParams,
				treeNodeModel.navigateParams
			);
			Object.assign(tempViewParams, _params);
		}
		return { tempContext, tempViewParams };
	}
}
